package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.mapper.*;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.common.cache.GuiGuCache;
import com.atguigu.tingshu.model.album.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@SuppressWarnings({"all"})
public class BaseCategoryServiceImpl extends ServiceImpl<BaseCategory1Mapper, BaseCategory1> implements BaseCategoryService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private BaseCategory2Mapper baseCategory2Mapper;

    @Autowired
    private BaseCategory3Mapper baseCategory3Mapper;


    @Autowired
    private BaseCategoryViewMapper baseCategoryViewMapper;


    /**
     * 查询所有1,2,3级分类列表（将子分类封装到categoryChild）
     */
    @Override
    @GuiGuCache(prefix = "category:all")
    public List<JSONObject> getBaseCategoryList() {
        //1.查询分类视图（封装1,2,3级分类所有数据）中所有数据 共计401条记录
        List<BaseCategoryView> allCategoryList = baseCategoryViewMapper.selectList(null);
        List<JSONObject> jsonObject1List = new ArrayList<>();
        //2.处理1级分类
        //2.1 对所有分类视图记录按1级分类ID分组得到Map Key：1级分类ID  Value：1级分类集合
        Map<Long, List<BaseCategoryView>> map1 = allCategoryList
                .stream()
                .collect(
                        Collectors.groupingBy(BaseCategoryView::getCategory1Id)
                );
        //2.2 遍历map1封装所有1级分类JSON对象
        for (Map.Entry<Long, List<BaseCategoryView>> entry1 : map1.entrySet()) {
            //2.2.1 获取1级分类ID
            Long category1Id = entry1.getKey();
            //2.2.2 获取1级分类名称
            String category1Name = entry1.getValue().get(0).getCategory1Name();
            //2.2.3 构建1级分类JSON对象
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("categoryId", category1Id);
            jsonObject1.put("categoryName", category1Name);
            //2.2.4 存入结果jsonObject1List中
            jsonObject1List.add(jsonObject1);
            //3. 处理2级分类
            List<JSONObject> jsonObject2List = new ArrayList<>();
            //3.1 对map1中集合进行根据2级分类ID进行分组 得到Map2 Key:二级分类ID Value：“二级”分类集合
            Map<Long, List<BaseCategoryView>> map2 =
                    entry1.getValue().stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //3.2 遍历map2 封装2级分类对象
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
                //3.2.1 获取2级分类ID
                Long category2Id = entry2.getKey();
                //3.2.2 获取2级分类名称
                String category2Name = entry2.getValue().get(0).getCategory2Name();
                //3.2.3 构建2级分类JSON对象
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("categoryId", category2Id);
                jsonObject2.put("categoryName", category2Name);
                jsonObject2List.add(jsonObject2);
                //4. 处理3级分类
                //4.1 创建三级分类JSON对象集合
                List<JSONObject> jsonObject3List = new ArrayList<>();
                //4.2 遍历"二级"分类集合 得到所有三级分类
                for (BaseCategoryView baseCategoryView : entry2.getValue()) {
                    //4.3 封装三级分类JSON对象
                    //4.3.1 获取3级分类ID
                    Long category3Id = baseCategoryView.getCategory3Id();
                    //4.3.2 获取3级分类名称
                    String category3Name = baseCategoryView.getCategory3Name();
                    //4.3.3 构建3级分类JSON对象
                    JSONObject jsonObject3 = new JSONObject();
                    jsonObject3.put("categoryId", category3Id);
                    jsonObject3.put("categoryName", category3Name);
                    //4.3.4 构建3级分类放入三级分类JSON对象
                    jsonObject3List.add(jsonObject3);
                }
                //4.4 将三级分类集合加入到二级分类对象中"categoryChild"属性中
                jsonObject2.put("categoryChild", jsonObject3List);
            }
            //3.3 将2级分类JSON集合加入到1级分类对象中"categoryChild"
            jsonObject1.put("categoryChild", jsonObject2List);

        }

        return jsonObject1List;
    }

    @Autowired
    private BaseAttributeMapper baseAttributeMapper;

    /**
     * 根据1级分类ID查询关联所有标签列表（标签值）
     *
     * @param category1Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "category:attributes")
    public List<BaseAttribute> getAttributesByCategory1Id(Long category1Id) {
        return baseAttributeMapper.getAttributesByCategory1Id(category1Id);
    }

    /**
     * 根据三级分类ID查询分类视图
     *
     * @param category3Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "category:category3:")
    public BaseCategoryView getCategoryView(Long category3Id) {
        return baseCategoryViewMapper.selectById(category3Id);
    }

    /**
     * 根据1级分类ID查询该分类置顶7个三级分类列表
     * <p>
     * #关联查询
     * EXPLAIN SELECT
     * bc3.id,
     * bc3.category2_id,
     * bc3.NAME
     * FROM
     * base_category3 bc3
     * INNER JOIN ( SELECT id FROM base_category2 WHERE category1_id = 1 ) bc2 ON bc2.id = bc3.category2_id;
     * WHERE
     * bc3.is_top = 1
     * ORDER BY
     * bc3.order_num
     * LIMIT 7;
     *
     * @param category1Id
     * @return
     */
    @Override
    @GuiGuCache(prefix = "category:top7:")
    public List<BaseCategory3> getTopBaseCategory3(Long category1Id) {
        //1.根据1级分类ID查询二级分类ID列表
        LambdaQueryWrapper<BaseCategory2> baseCategory2LambdaQueryWrapper = new LambdaQueryWrapper<>();
        baseCategory2LambdaQueryWrapper.eq(BaseCategory2::getCategory1Id, category1Id);
        baseCategory2LambdaQueryWrapper.select(BaseCategory2::getId);
        List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(baseCategory2LambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(baseCategory2List)) {
            List<Long> baseCategory2IdList = baseCategory2List.stream().map(BaseCategory2::getId).collect(Collectors.toList());

            //2.根据二级分类ID列表、是否置顶、按照序号进行排序、获取7条分类记录
            LambdaQueryWrapper<BaseCategory3> baseCategory3LambdaQueryWrapper = new LambdaQueryWrapper<>();
            baseCategory3LambdaQueryWrapper.eq(BaseCategory3::getIsTop, 1);
            baseCategory3LambdaQueryWrapper.in(BaseCategory3::getCategory2Id, baseCategory2IdList);
            baseCategory3LambdaQueryWrapper.select(BaseCategory3::getId, BaseCategory3::getCategory2Id, BaseCategory3::getName);
            baseCategory3LambdaQueryWrapper.orderByAsc(BaseCategory3::getOrderNum);
            baseCategory3LambdaQueryWrapper.last("limit 7");
            return baseCategory3Mapper.selectList(baseCategory3LambdaQueryWrapper);
        }
        return null;
    }

    /**
     * 根据1级分类ID查询一级分类及包含2,3级分类信息
     *
     * @param category1Id
     * @return 1级分类对象
     */
    @Override
    @GuiGuCache(prefix = "category:info:")
    public JSONObject getBaseCategoryListByCategory1Id(Long category1Id) {
        //1.查询分类视图获取一级分类ID所有视图记录
        LambdaQueryWrapper<BaseCategoryView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseCategoryView::getCategory1Id, category1Id);
        List<BaseCategoryView> list = baseCategoryViewMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            //2.处理1级分类
            BaseCategoryView baseCategoryView = list.get(0);
            String category1Name = baseCategoryView.getCategory1Name();
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("categoryId", category1Id);
            jsonObject1.put("categoryName", category1Name);
            //3.处理2级分类
            //3.1 将"1级分类"列表，根据2级分类ID进行分组
            Map<Long, List<BaseCategoryView>> map2 =
                    list.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //3.2 遍历"2级"分类Map 封装2级分类集合
            List<JSONObject> jsonObject2List = new ArrayList<>();
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
                Long category2Id = entry2.getKey();
                String category2Name = entry2.getValue().get(0).getCategory2Name();
                //3.2.1 创建2级分类JSON对象
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("categoryId", category2Id);
                jsonObject2.put("categoryName", category2Name);
                jsonObject2List.add(jsonObject2);

                //4.处理3级分类
                List<JSONObject> jsonObject3List = new ArrayList<>();
                //4.1 遍历“3级”列表
                for (BaseCategoryView categoryView : entry2.getValue()) {
                    //4.2 创建3级分类JSON对象
                    Long category3Id = categoryView.getCategory3Id();
                    String category3Name = categoryView.getCategory3Name();
                    JSONObject jsonObject3 = new JSONObject();
                    jsonObject3.put("categoryId", category3Id);
                    jsonObject3.put("categoryName", category3Name);
                    jsonObject3List.add(jsonObject3);
                }
                //4.3 将三级分类集合放入二级分类对象中"categoryChild"
                jsonObject2.put("categoryChild", jsonObject3List);
            }

            //2.1 将二级分类集合放入到一级分类对象中"categoryChild"
            jsonObject1.put("categoryChild", jsonObject2List);
            return jsonObject1;
        }
        return null;
    }
}
